﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Claims;
using System.Text;
using System.Web;
using System.Xml;
using BoYuanCore.DBServices.Base;
using FineUICore;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.RazorPages;


namespace BoYuanCore.WebForm.Code
{
    [Authorize]
    public class BaseModel : PageModel
    {
        /// <summary>
        /// 项目是否包含button权限
        /// </summary>
        public const bool HaveButtonPermissions = false;//如果包含请设置为true

        /// <summary>
        /// 全局DB访问对象,简化写法,可以直接支持事务。
        /// </summary>
        public static IFreeSql DB = FreeSqlHelper.Fsql;

        /// <summary>
        /// 获取当前用户id
        /// </summary>
        /// <returns></returns>
        protected long GetUserID()
        {
            ClaimsPrincipal principal = HttpContext.User;
            if (null != principal)
            {
                foreach (Claim claim in principal.Claims)
                {
                    if (claim.Type == "userid")
                    {
                        return Convert.ToInt64(claim.Value);
                    }
                }
            }
            return 0;
        }


        #region IsPostBack

        /// <summary>
        /// 是否页面回发
        /// </summary>
        public bool IsPostBack
        {
            get
            {
                return FineUICore.PageContext.IsFineUIAjaxPostBack();
            }
        }

        #endregion

        #region RegisterStartupScript

        /// <summary>
        /// 注册客户端脚本
        /// </summary>
        /// <param name="scripts"></param>
        public void RegisterStartupScript(string scripts)
        {
            FineUICore.PageContext.RegisterStartupScript(scripts);
        }

        #endregion

        #region ViewBag

        private DynamicViewData _viewBag;

        /// <summary>
        /// Add ViewBag to PageModel
        /// https://forums.asp.net/t/2128012.aspx?Razor+Pages+ViewBag+has+gone+
        /// https://github.com/aspnet/Mvc/issues/6754
        /// </summary>
        public dynamic ViewBag
        {
            get
            {
                if (_viewBag == null)
                {
                    _viewBag = new DynamicViewData(ViewData);
                }
                return _viewBag;
            }
        }
        #endregion

        #region 实用函数

        /// <summary>
        /// 获取回发的参数
        /// </summary>
        /// <returns></returns>
        public string GetRequestEventArgument()
        {
            return Request.Form["__EVENTARGUMENT"];
        }

        /// <summary>
        /// 获取回发的参数列表
        /// </summary>
        /// <returns></returns>
        public string[] GetRequestEventArguments()
        {
            var arg = GetRequestEventArgument();
            return arg.Split("$");
        }

        #region Alert 或 页面跳转

        /// <summary>
        /// 提示信息(弹层用),并指定父页面跳转
        /// </summary>
        /// <param name="message">内容</param>
        /// <param name="url">跳转地址</param>
        /// <param name="js">显示消息后 执行的js</param>
        protected void AlertInforAndRedirect(string message, string url, string js = "")
        {
            FineUICore.Alert aa = new FineUICore.Alert();
            aa.AlertInforAndRedirect(message, url, js);
        }

        /// <summary>
        /// 提示信息(弹层用)
        /// </summary>
        /// <param name="message">内容</param>
        /// <param name="isPostBackReference">是否回发刷新页面</param>
        /// <param name="js">显示消息后 执行的js</param>
        protected void AlertInfor(string message, bool isPostBackReference = true, string js = "")
        {
            FineUICore.Alert aa = new FineUICore.Alert();
            aa.AlertInfor(message, isPostBackReference, js);
        }

        /// <summary>
        /// 提示信息（单页用 并刷新当前页）
        /// </summary>
        /// <param name="message">内容</param>
        /// <param name="isPostBackReference">是否回发刷新页面</param>
        /// <param name="js">显示消息后 执行的js</param>
        protected void AlertInforBySingerPage(string message, bool isPostBackReference = true, string js = "")
        {
            FineUICore.Alert aa = new FineUICore.Alert();
            aa.AlertInforBySingerPage(message, isPostBackReference, js);

        }

        /// <summary>
        /// 报错信息
        /// </summary>
        /// <param name="message">内容</param>
        /// <param name="isPostBackReference">是否回发刷新页面</param>
        /// <param name="js">显示消息后 执行的js</param>
        protected void AlertError(string message, bool isPostBackReference = true, string js = "")
        {
            FineUICore.Alert aa = new FineUICore.Alert();
            aa.AlertError(message, isPostBackReference, js);
        }

        /// <summary>
        /// 成功信息
        /// </summary>
        /// <param name="message">内容</param>
        /// <param name="isPostBackReference">是否回发刷新页面</param>
        /// <param name="js">显示消息后 执行的js</param>
        protected void AlertSuccess(string message, bool isPostBackReference = true, string js = "")
        {
            FineUICore.Alert aa = new FineUICore.Alert();
            aa.AlertSuccess(message, isPostBackReference, js);
        }

        /// <summary>
        /// 疑问信息
        /// </summary>
        /// <param name="message">内容</param>
        /// <param name="isPostBackReference">是否回发刷新页面</param>
        /// <param name="js">显示消息后 执行的js</param>
        protected void AlertQuestion(string message, bool isPostBackReference = true, string js = "")
        {
            FineUICore.Alert aa = new FineUICore.Alert();
            aa.AlertQuestion(message, isPostBackReference, js);
        }

        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="message">内容</param>
        /// <param name="isPostBackReference">是否回发刷新页面</param>
        /// <param name="js">显示消息后 执行的js</param>
        protected void AlertWarning(string message, bool isPostBackReference = true, string js = "")
        {
            FineUICore.Alert aa = new FineUICore.Alert();
            aa.AlertWarning(message, isPostBackReference, js);
        }

        #endregion

        #region Notify 消息框

        /// <summary>
        /// 信息消息框
        /// </summary>
        /// <param name="message">警告信息</param>
        /// <param name="js">然后执行的js代码</param>
        public void NotifyInformation(string message, string js = null)
        {
            NotifyBase(message, js, MessageBoxIcon.Information);
        }

        /// <summary>
        /// 问题消息框
        /// </summary>
        /// <param name="message">警告信息</param>
        /// <param name="js">然后执行的js代码</param>
        public void NotifyQuestion(string message, string js = null)
        {
            NotifyBase(message, js, MessageBoxIcon.Question);
        }

        /// <summary>
        /// 警告消息框
        /// </summary>
        /// <param name="message">警告信息</param>
        /// <param name="js">然后执行的js代码</param>
        public void NotifyWarning(string message, string js = null)
        {
            NotifyBase(message, js, MessageBoxIcon.Warning);
        }

        /// <summary>
        /// 错误消息框
        /// </summary>
        /// <param name="message">错误信息</param>
        /// <param name="js">然后执行的js代码</param>
        public void NotifyError(string message, string js = null)
        {
            NotifyBase(message, js, MessageBoxIcon.Error);
        }

        /// <summary>
        /// 成功消息框
        /// </summary>
        /// <param name="message">错误信息</param>
        /// <param name="js">然后执行的js代码</param>
        public void NotifySuccess(string message, string js = null)
        {
            NotifyBase(message, js, MessageBoxIcon.Success);
        }

        private void NotifyBase(string message, string js = null, FineUICore.MessageBoxIcon icon = MessageBoxIcon.Information)
        {
            Notify nf = new Notify();
            nf.GetShowNotify();
            nf.Message = message;
            nf.MessageBoxIcon = icon;
            if (!string.IsNullOrEmpty(js)) nf.HideScript = js;
            nf.Show();
        }

        #endregion

        /// <summary>
        /// 获取网址的完整路径
        /// </summary>
        /// <param name="virtualPath"></param>
        /// <returns></returns>
        public string GetAbsoluteUrl(string virtualPath)
        {
            // http://benjii.me/2015/05/get-the-absolute-uri-from-asp-net-mvc-content-or-action/
            var urlBuilder = new System.UriBuilder(Request.GetDisplayUrl())
            {
                Path = Url.Content(virtualPath),
                Query = null,
            };

            return urlBuilder.ToString();
        }

        #endregion
        
        #region DataView - RowFilter

        // From: http://www.csharp-examples.net/dataview-rowfilter/
        public static string EscapeLikeValue(string valueWithoutWildcards)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < valueWithoutWildcards.Length; i++)
            {
                char c = valueWithoutWildcards[i];
                if (c == '*' || c == '%' || c == '[' || c == ']')
                    sb.Append("[").Append(c).Append("]");
                else if (c == '\'')
                    sb.Append("''");
                else
                    sb.Append(c);
            }
            return sb.ToString();
        }



        #endregion

        #region override - OnPageHandlerExecuting

        public override void OnPageHandlerExecuting(PageHandlerExecutingContext context)
        {
            base.OnPageHandlerExecuting(context);

            if (IsPostBack)
            {
                // 回发请求时，检索请求数据或者Cookie，来验证当前访问是否有效。请求无效时，弹出错误提示，不再执行Page_Load和回发事件。
                if (!String.IsNullOrEmpty(Request.Query["error"]))
                {
                    NotifyError("身份验证失败！");

                    // https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.filters.pagehandlerexecutingcontext?view=aspnetcore-8.0
                    // Setting Result to a non-null value inside a page filter will short-circuit the page and any remaining page filters.
                    // 设置context.Result=UIHelper.Result()，可以中断页面继续执行（跳过接下来的 Page_Load 和回发事件）。
                    context.Result = UIHelper.Result();
                }
            }
        }

        #endregion
    }
}
